import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import LayerManager from "./LayerManager";
import { Fill, Icon, Stroke, Style, Text } from "ol/style";
import { Feature } from "ol";
import { Point } from "ol/geom";
import { MapUtils } from "./MapUtils";
import { GeoJSONManager } from "./layerDataManager";
import { ElMessage } from 'element-plus';
import { eventBus } from './EventBus'; // 事件总线



// 定义航迹图层管理器
export interface ModelStyleOptions {
    id: string,
    iconSrc?: string;
    modelName: string;
    time: number;
    heading?: number; // 旋转角度
    scale?: number;   // 缩放比例
    coordinates: Array<any>; // 模型坐标
    remarks?: any; // 备注
}

let maintainTrajectoryData: any = {} // 保存航迹数据


//  工具函数：创建样式
class StyleUtils {
    static createTextStyle(modelName: string) {
        return new Text({
            text: modelName,
            scale: 1.5,
            offsetY: -35,
            fill: new Fill({ color: '#FFF' }),
            stroke: new Stroke({ color: '#000000', width: 2 }),
            backgroundFill: new Fill({ color: 'rgba(0, 0, 0, 0.5)' }),
            padding: [5, 5, 5, 5],
        });
    }

    static createIconStyle(src: string, heading: number, scale: number) {
        return new Icon({
            src: src,
            scale: scale,
            rotation: this.degreesToRadians(heading),
            anchor: [0.5, 0.5]
        });
    }

    static degreesToRadians(degrees: number): number {
        return (degrees * Math.PI) / 180;
    }
}

// 模型管理：处理模型的添加、更新和移除
class ModelManager {
    public static layerMgr: LayerManager; // 图层管理器
    
    // 初始化图层管理器
    private static initLayerManager() {
        if (!this.layerMgr) {
            const olMap = (window as any).olMap;
            if (!olMap || !olMap.layerManager) {
                throw new Error('Map or LayerManager not initialized');
            }
            this.layerMgr = olMap.layerManager;
        }
    }

    // 添加模型
    static addModel(modelStyle: ModelStyleOptions) {
        try {
            this.initLayerManager(); // 确保图层管理器已初始化
            
            const vectorSource = new VectorSource(); // 创建矢量数据源
            const vectorLayer = new VectorLayer({ source: vectorSource, zIndex: 2 });  // 创建矢量图层
            const modelFeature = this.setModelStyle(modelStyle); // 创建模型样式
            this.addFeatureToLayer(modelFeature, vectorLayer);   // 将模型样式添加到图层
            this.layerMgr.addLayer(vectorLayer, modelStyle.id, true); // 将图层添加到图层管理器

            TrajectoryManager.createTrajectory(modelStyle.id + "_line", []); // 创建航迹
        } catch (error) {
            console.error('Failed to add model:', error);
            // 可以在这里添加错误处理逻辑
        }
    }

    // 修改模型样式
    static updateFeature(modelStyle: ModelStyleOptions) {
        const modelFeature = this.setModelStyle(modelStyle); // 创建模型样式
        this.layerMgr.updateLayer(modelStyle.id, [modelFeature]); // 更新图层，传入数组
    }

    // 创建模型样式
    static setModelStyle({ iconSrc, modelName, heading, scale, coordinates }: ModelStyleOptions) {
        const textStyle = StyleUtils.createTextStyle(modelName); // 创建文本样式
        const iconStyle = StyleUtils.createIconStyle(iconSrc as string, heading as number, scale as number); // 创建图标样式
        const feature = this.createFeature(coordinates); // 创建 Feature
        feature.setStyle(new Style({
            image: iconStyle, // 图标样式
            text: textStyle,  // 文本样式
        }));

        return feature;
    }

    // 创建一个 Feature
    static createFeature(coordinates: number[]) {
        return new Feature({
            geometry: new Point(MapUtils.lonLatToMapCoord(coordinates[0], coordinates[1])),
        });
    }

    // 将 Feature 添加到图层
    static addFeatureToLayer(feature: Feature, vectorLayer: VectorLayer) {
        vectorLayer.getSource()?.addFeature(feature);
    }

    // 移除图层上的模型
    static clearModelById(modelId: string) {
        this.layerMgr.removeLayer(modelId);
        if (maintainTrajectoryData[modelId + "_line"]) {
            delete maintainTrajectoryData[modelId + "_line"]; // 删除航迹
        }
    }
}


// 插值管理器，处理飞行移动和姿态变化
class InterpolationManager {
    // 插值管理器需要一个模型样式缓存
    static lastModelStyle: ModelStyleOptions | null = null;
    static lastUpdateTime: number = 0;

    // 更新模型的位置和旋转
    static updateModelPosition(
        currentData: ModelStyleOptions,
        Time: number // 用来控制插值的时间差
    ) {
        if (this.lastModelStyle) {
            // 计算插值进度 t =Time / timeDifference
            const timeDiff = currentData.time - this.lastUpdateTime; // 时间差
            const t = Time / timeDiff;

            const lastCoordinate = this.lastModelStyle.coordinates
            const currentCoordinate = currentData.coordinates
            // 插值位置
            const interpolatedPosition = this.interpolatePosition(
                lastCoordinate as [number, number],
                currentCoordinate as [number, number],
                t
            );

            // 插值旋转角度
            const interpolatedHeading = this.calculateHeading(lastCoordinate[1], lastCoordinate[0], currentCoordinate[1], currentCoordinate[0]);

            // 更新模型样式
            this.updateModel({
                ...currentData,
                coordinates: interpolatedPosition,
                heading: interpolatedHeading
            });
        }

        // 保存当前数据以供下次计算
        this.lastModelStyle = currentData;
        this.lastUpdateTime = currentData.time;
    }

    // 位置插值
    static interpolatePosition(startCoords: [number, number], endCoords: [number, number], t: number): [number, number] {
        const lat = startCoords[0] + t * (endCoords[0] - startCoords[0]);
        const lon = startCoords[1] + t * (endCoords[1] - startCoords[1]);
        return [lat, lon];
    }


    // 假设飞机当前位置经纬度为 lat1, lon1，目标位置经纬度为 lat2, lon2
    static calculateHeading(lat1: number, lon1: number, lat2: number, lon2: number) {
        // 原有计算代码
        lat1 = lat1 * Math.PI / 180;
        lon1 = lon1 * Math.PI / 180;
        lat2 = lat2 * Math.PI / 180;
        lon2 = lon2 * Math.PI / 180;

        const deltaLon = lon2 - lon1;
        const X = Math.cos(lat2) * Math.sin(deltaLon);
        const Y = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(deltaLon);
        const bearing = Math.atan2(X, Y);

        let bearingDegrees = (bearing * 180 / Math.PI + 360) % 360;
        return Number(bearingDegrees.toFixed(4));
    }

    // 更新模型的样式（调用 ModelManager 更新飞行器位置）
    static updateModel(modelStyle: ModelStyleOptions) {
        ModelManager.updateFeature(modelStyle);

        // 分发事件，通知其他模块更新
        FlightDataReceiver.dispatchFlightData(modelStyle)
    }

    // 初始化插值管理器
    static reset() {
        this.lastModelStyle = null;
        this.lastUpdateTime = 0;
    }
}

// 轨迹管理器，处理轨迹绘制
class TrajectoryManager {
    // 生成航迹
    static createTrajectory = (id: string, dataPath: Array<any>) => {
        const geojson = GeoJSONManager.convertToLine(dataPath);
        const geoLayer = GeoJSONManager.loadMoreGeoJSON([geojson]);
        geoLayer.setZIndex(1)
        ModelManager.layerMgr.addLayer(geoLayer, id, true)
        // 维护本地航迹数据
        maintainTrajectoryData[id] = []
    }
    // 添加轨迹点
    static addTrajectoryPoint = (id: string, dataPath: Array<any>) => {

        maintainTrajectoryData[id].push([dataPath[0], dataPath[1]])
        let Path = maintainTrajectoryData[id]


        const geoLayer = ModelManager.layerMgr.getLayerById(id);
        let source = geoLayer?.getSource()
        // 如果源不存在，直接返回
        if (!source) {
            console.error('Layer source not found');
            return;

        }
        source?.clear()
        const geojson = GeoJSONManager.convertToLine(Path);
        const newSource = GeoJSONManager.getGeoSource([geojson], "EPSG:3857")
        let oldDataCount = Path.length
        // 优化数据
        if (Path > 1000) {
            Path = Path.filter((_: any, index: number) => index % 50 === 0);
            ElMessage.warning(`已优化数据，原数据量：${oldDataCount - Path.length}，现数据量：${Path.length}`);
        }
        const features = newSource.getFeatures()
        source?.addFeatures(features)
    }




}

// 更新飞行器
class FlightDataReceiver {
    static lastTime: number = 0;
    // 接收飞行数据并处理插值更新
    static receiveFlightData(newData: ModelStyleOptions) {
        if (!maintainTrajectoryData[newData.id + '_line']) {
            ModelManager.addModel(newData);
        }
        const currentTime = Date.now();
        // 调用插值管理器更新模型
        InterpolationManager.updateModelPosition(newData, 1);
        // 添加轨迹信息
        TrajectoryManager.addTrajectoryPoint(newData.id + '_line', newData.coordinates);
        // 更新上次接收时间
        this.lastTime = currentTime;
    }
    // 分发飞行数据
    static dispatchFlightData(data: any) {
        // 触发自定义事件，传递经纬度
        eventBus.dispatchEvent('dispatchFlightData', data);
    }

}



export { ModelManager, FlightDataReceiver };